<?php


namespace app\home\controller;


use app\base\BaseController;
use think\Exception;
use think\facade\Db;
use think\facade\View;

/**
 * Class SaleReconcile
 * @package app\home\controller
 * 采购对账单
 */
class BuyReconcile extends BaseController
{
    protected $table='sale_reconcile';
    protected $title='采购对账单';
    private $sessionKey='pageBuyReconcile';
    /**
     * @return \json|\think\response\View
     * @throws \think\db\exception\DbException
     * date:2024/5/8
     */
    public function index()
    {
        if (request()->isAjax()) {
            $param=$this->param;
            $where[]=['pp.status','>',-1];
            if (isset($this->param['status'])&&$this->param['status']){
                $where[]=['pp.status','=',$this->param['status']];
            }
            $where[]=['pp.s_type','=',1];
            foreach (['p_code','p_name','md_bar_code','md_name','md_brand','md_specs','username'] as $v){
                if ($v=='md_bar_code'){
                    $k='md.bar_code';
                }else{
                    $k=str_replace('_','.',$v);
                }
                if (isset($this->param[$v])&&$this->param[$v]){
                    $where[]=[$k,'like','%'.$this->param[$v].'%'];
                }
            }
            if (isset($this->param['oderNum'])&&$this->param['oderNum']){
                $where[]=['pp.orderNum','like','%'.$this->param['oderNum'].'%'];
            }
            if (isset($this->param['ywlx'])&&$this->param['ywlx']){
                if ($param['ywlx']=='罚款单'){
                    $sb_ids=Db::name('purveyor_ticket')->where('status','>',-1)
                        ->where('type','=',1)->column('id');
                    $where[]=['punter_ticket_id','in',$sb_ids];
                }elseif ($param['ywlx']=='其他收入'){
                    $sb_ids=Db::name('purveyor_ticket')->where('status','>',-1)
                        ->where('type','=',2)->column('id');
                    $where[]=['punter_ticket_id','in',$sb_ids];
                }else{
                    $sb_ids=Db::name('sale_hanging_bill')
                        ->where('status','>',-1)
                        ->where('type','like','%'.$param['ywlx'].'%')->column('id');
                    $where[]=['sale_hanging_bill_id','in',$sb_ids];
                }
            }
            if (isset($this->param['ydBm'])&&$this->param['ydBm']){
                $sb_ids1=Db::name('purveyor_ticket')->where('status','>',-1)
                    ->where('orderNum','like',"%".$param['ydBm'].'%')->column('id');
                $sb_ids2=Db::name('sale_hanging_bill')
                    ->where('status','>',-1)
                    ->where('g_orderNum','like','%'.$param['ydBm'].'%')->column('id');
                if ($sb_ids1&&!$sb_ids2){
                    $where[]=['pp.punter_ticket_id','in',$sb_ids1];
                }
                if ($sb_ids2&&!$sb_ids1){
                    $where[]=['pp.sale_hanging_bill_id','in',$sb_ids2];
                }
                if ($sb_ids1&&$sb_ids2){
                    $sb_ids=$sb_ids1+$sb_ids2;
                    $where[]=['sale_hanging_bill_id|punter_ticket_id','in',$sb_ids];
                }
            }
            if (isset($this->param['reconcileDate'])&&$this->param['reconcileDate']){
                $rTimes=explode('~',$param['reconcileDate']);
                $where[]=['pp.reconcileDate','between',$rTimes];
            }
            session($this->sessionKey,$where);
            $rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
            $list = Db::name($this->table)->alias('pp')
                ->join('material_dossier md','md.id=pp.material_dossier_id','left')
                ->join('purveyor p','p.id=pp.punter_id','left')
                ->where($where)
                ->field("pp.*,md.bar_code,md.name as mdName,md.specs,p.name as pName")
                ->paginate($rows)->each(function ($item){
                    if ($item['reconcile_type']==1){
                        $shbInfo=Db::name('sale_hanging_bill')->where('id',$item['sale_hanging_bill_id'])
                            ->field('g_orderNum,type')->find();
                        $item['fromOrderNum']=$shbInfo['g_orderNum'];
                        $item['ywlx']=$shbInfo['type'];//业务类型
                    }else{
                        $tiketInfo=Db::name('purveyor_ticket')
                            ->where('id',$item['punter_ticket_id'])->field('orderNum,type')->find();
                        $item['fromOrderNum']=$tiketInfo['orderNum'];
//                        if ($tiketInfo['type']==1){
//                            $item['reconcilePrice']='-'.$item['reconcilePrice'];
//                        }
                        $item['ywlx']=$tiketInfo['type']==1?'罚款单':'其他收入';
                    }
                    $item['skMoney']=Db::name('receipt_order_detail')
                        ->where('status',2)
                        ->where('sale_reconcile_id',$item['id'])->sum('money');
                    return $item;
                });
            return table_assign(0, '', $list);
        } else {
            return view();
        }
    }

    /**
     * @return \json|\think\response\View
     * @throws \think\db\exception\DbException
     * date:2024/5/12
     * 新增产品对账
     */
    public function addMx()
    {
        $param=$this->param;
        if (request()->isPost()) {
            $where[]=['pp.status','in',[1,2]];
            $where[]=['pp.h_type','=',1];
            foreach (['bar_code','mdName','specs'] as $v){

                if (isset($this->param[$v])&&$this->param[$v]){
                    $k=$v;
                    if ($v=='mdName'){
                        $k="md.name";
                    }
                    $where[]=[$k,'like','%'.$this->param[$v].'%'];
                }
            }
            $rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
            $list = Db::name('sale_hanging_bill')->alias('pp')
                ->join('material_dossier md','md.id=pp.material_dossier_id')
                ->join('purveyor p','p.id=pp.punter_id','left')
                ->join('admin a','a.id=pp.create_user','left')
                ->where($where)
                ->field("pp.*,md.bar_code,md.name as mdName,md.unit,md.specs,p.name as pName,p.code as pCode")
                ->paginate($rows)->each(function ($item,$index){
                    $yiduizhang=Db::name($this->table)
                        ->where('status',2)
                        ->where('punter_id',$item['punter_id'])
                        ->where('material_dossier_id',$item['material_dossier_id'])
                        ->where('sale_hanging_bill_id',$item['id'])->sum('reconcileNum');
                    $item['unReconcile']=$item['num']-$yiduizhang;
                    $item['reconcileNum']='';
                    $item['reconcilePrice']=0;
                    $item['unitPirce']=Db::name('purveyor_price')
                        ->where('status',1)
                        ->where('purveyor_id',$item['punter_id'])
                        ->where('material_dossier_id',$item['material_dossier_id'])
                        ->where('time','=',date('Y-m'))
                        ->order('time DESC')
                        ->limit(1)
                        ->value('price');
                    return $item;
                });
            \think\facade\View::assign('list',$list);
            return table_assign(0, '', $list);
        } else {
            return \view('mx');
        }
    }

    /**
     * date:2024/5/14
     * 金额对账
     */
    public function addPrice()
    {
        $param=$this->param;
        if (request()->isPost()) {
            $ids=Db::name($this->table)->where('status','>',-1)
                ->where('s_type',1)
                ->column('punter_ticket_id');
            $where[]=['pt.status','=',1];
            $where[]=['pt.t_type','=',1];
            $where[]=['pt.id','not in',$ids];
            if (isset($param['p_Name'])&&$param['p_Name']){
                $where[]=['p.name','like',"%{$param['p_Name']}%"];
            }
            if (isset($param['pt_type'])&&$param['pt_type']){
                $where[]=['pt.type','=',$param['pt_type']];
            }
            $rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
            $list = Db::name('purveyor_ticket')->alias('pt')
                ->join('purveyor p','p.id=pt.purveyor_id')
                ->where($where)
                ->field('pt.*,p.name as pName,p.code as pCode')
                ->paginate($rows)->each(function ($item,$index){
                    $item['reconcilePrice']=$item['type']==1?-$item['price']:$item['price'];
                    return $item;
                });
            \think\facade\View::assign('list',$list);
            return table_assign(0, '', $list);
        } else {
            return \view('priceMx');
        }
}
    /**
     * @return \json|\think\response\View
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * date:2024/5/12
     * 编辑
     */
    public function add()
    {

        if (request()->isAjax()) {
            $postData=$this->param;
            $isAdd=$postData['add']??'';
            if ($isAdd){
                $sRData=$postData['data'];
                if (!$sRData){
                    return to_assign(1,'参数缺失');
                }
                foreach ($sRData as &$v){
                    $v['orderNum']=orderNum('CGDZ');
                    $v['s_type']=1;
                    $v['unitPirce']=$v['unitPirce']??0;
                    $v['reconcileNum']=$v['reconcileNum']??0;
                    $v['create_time']=time();
                    $v['update_time']=time();
                }
                Db::name($this->table)->insertAll($sRData);
                add_log('add', '', $postData,$this->title);
            }else{
                $postData['update_time']=time();
                Db::name($this->table)->save($postData);
                add_log('edit', $postData['id'], $postData,$this->title);
            }
            return  to_assign();

        }else{
            $id = isset($this->param['id']) ? $this->param['id'] : 0;
            if ($id > 0) {
                $detail =Db::name($this->table)->alias('pp')
                    ->join('material_dossier md','md.id=pp.material_dossier_id','left')
                    ->join('purveyor p','p.id=pp.punter_id','left')
                    ->where('pp.id',$id)
                    ->field("pp.*,md.bar_code,md.name as mdName,md.specs,p.name as pName")
                    ->find();

                $yiduizhang=Db::name($this->table)
                    ->where('status',2)
                    ->where('sale_hanging_bill_id',$detail['sale_hanging_bill_id'])->sum('reconcileNum');
                $detail['num']=Db::name('sale_hanging_bill')
                    ->where('id',$detail['sale_hanging_bill_id'])->value('num');
                $detail['unReconcile']=$detail['num']-$yiduizhang;
                $detail['unitPirce']=Db::name('purveyor_price')
                    ->where('status',1)
                    ->where('purveyor_id',$detail['punter_id'])
                    ->where('material_dossier_id',$detail['material_dossier_id'])
                    ->where('time','=',date('Y-m'))
                    ->order('id DESC')
                    ->limit(1)
                    ->value('price');

                View::assign('detail', $detail);
            }

            View::assign('id', $id);

            return  View('form');
        }
    }

    public function onSure()
    {
        $id=$this->param['id']??0;
        if (!$id){
            return to_assign(1,'参数缺失');
        }
        $info=Db::name($this->table)->where('id','in',$id)
            ->field("*,(select num from fy_sale_hanging_bill shb where shb.id=sale_hanging_bill_id)num")
            ->select();
        if (!$info){
            return to_assign(1,'参数有误');
        }
        Db::startTrans();
        try {
          foreach ($info as $v){
              if ($v['status']!=1){
                  throw new Exception('已确认数据无需再次确认');
              }
              if ($v['reconcile_type']==1){
                  $yiduizhang=Db::name($this->table)
                      ->where('status',2)
                      ->where('sale_hanging_bill_id',$v['sale_hanging_bill_id'])->sum('reconcileNum');
                  $weiDuizhang=$v['num']-$yiduizhang;
                  if (abs($v['reconcileNum'])>abs($weiDuizhang)){
                      throw new Exception('对账数量大于未对账数据量');
                  }
                  $status=2;
                  if ($weiDuizhang==$v['reconcileNum']){
                      $status=3;
                  }
                  Db::name('sale_hanging_bill')
                      ->where('id',$v['sale_hanging_bill_id'])
                      ->update(['update_time'=>time(),'status'=>$status]);

              }else{
                  Db::name('purveyor_ticket')->where('id',$v['punter_ticket_id'])
                      ->update(['status'=>2,'update_time'=>time()]);
              }
              Db::name($this->table)->where('id','in',$v['id'])->update(['checkUser'=>$this->uid,'status'=>2,'reconcileDate'=>date('Y-m-d'),'update_time'=>time(),'checkTime'=>time()]);

          }
          add_log('check', $id, $this->param,$this->title);
            Db::commit();

        }catch (\Exception $e){
            Db::rollback();
            return to_assign(1,'操作失败:'.$e->getMessage());
        }
        return to_assign(0,'操作成功');
    }

    public function delete()
    {
        if (request()->isDelete()) {
            $id = get_params("id");
            $status=Db::name($this->table)->where('id','in',$id)->column('status');
            if (in_array('2',$status)){
                return  to_assign(1, "有已确认数据，不能删除");
            }
            try {
                Db::name($this->table)->where('id','in',$id)->update(['status'=>-1,'deleted'=>time()]);
                add_log('delete', $id, request()->param(),$this->title);
            }catch (\Exception $e){
                return to_assign(1, "删除失败".$e->getMessage());
            }
            return to_assign(0, "删除成功");
        } else {
            return to_assign(1, "错误的请求");
        }
    }

    public function onCancel()
    {
        $id=$this->param['id']??0;
        if (!$id){
            return to_assign(1,'参数缺失');
        }
        $info=Db::name($this->table)->where('id','in',$id)
            ->where('status',2)
            ->field("*,(select num from fy_sale_hanging_bill shb where shb.id=sale_hanging_bill_id)num")
            ->select();
        if (!$info){
            return to_assign(1,'参数有误');
        }
        Db::startTrans();
        try {
            foreach ($info as $v){
               if ($v['reconcile_type']==1){
                   $yiduizhang=Db::name($this->table)
                       ->where('status',2)
                       ->where('sale_hanging_bill_id',$v['sale_hanging_bill_id'])->sum('reconcileNum');
                   $weiDuizhang=$v['num']-$yiduizhang;
                   $status=2;
                   if ($weiDuizhang+$v['reconcileNum']==$v['num']){
                       $status=1;
                   }
                   Db::name('sale_hanging_bill')
                       ->where('id',$v['sale_hanging_bill_id'])
                       ->update(['update_time'=>time(),'status'=>$status]);
               }else{
                   Db::name('purveyor_ticket')
                       ->where('id',$v['punter_ticket_id'])
                       ->update(['status'=>1,'update_time'=>time()]);
               }
            }
            Db::name($this->table)->where('id','in',$id)->where('status',2)
                ->update(['checkUser'=>$this->uid,'status'=>1,'is_end'=>2,'reconcileDate'=>null,'update_time'=>time(),'checkTime'=>time()]);

            add_log('back', $id, $this->param,$this->title);
            Db::commit();
        }catch (\Exception $e){
            Db::rollback();
            return to_assign(1,'操作失败:'.$e->getMessage());
        }
        return to_assign(0,'操作成功');
    }

    public function exportData()
    {
        $where=session($this->sessionKey);
        $mStatus=['','草稿','已确认'];
        $list = Db::name($this->table)->alias('pp')
            ->join('material_dossier md','md.id=pp.material_dossier_id','left')
            ->join('purveyor p','p.id=pp.punter_id','left')
            ->where($where)
            ->field("pp.*,md.bar_code,md.name as mdName,md.specs,p.name as pName")
            ->select()
            ->each(function ($item,$index) use ($mStatus){
                if ($item['reconcile_type']==1){
                    $shbInfo=Db::name('sale_hanging_bill')->where('id',$item['sale_hanging_bill_id'])
                        ->field('g_orderNum,type')->find();
                    $item['fromOrderNum']=$shbInfo['g_orderNum'];
                    $item['ywlx']=$shbInfo['type'];//业务类型
                }else{
                    $tiketInfo=Db::name('purveyor_ticket')
                        ->where('id',$item['punter_ticket_id'])->field('orderNum,type')->find();
                    $item['fromOrderNum']=$tiketInfo['orderNum'];
//                        if ($tiketInfo['type']==1){
//                            $item['reconcilePrice']='-'.$item['reconcilePrice'];
//                        }
                    $item['ywlx']=$tiketInfo['type']==1?'罚款单':'其他收入';
                }
                $item['skMoney']=Db::name('receipt_order_detail')
                    ->where('status',2)
                    ->where('sale_reconcile_id',$item['id'])->sum('money');
                return $item;
            });
        $title = [
//            'id' => 'ID',
            'orderNum' => '单据编码',
            'pName' => '供应商名称',
            'bar_code' => '产品编码',
            'mdName' => '产品名称',
            'specs' => '规格型号',
            'ywlx' => '业务类型',
            'fromOrderNum' => '源单编码',
            'reconcileNum' => '对账数量',
            'reconcilePrice' => '对账金额',
            'skMoney' => '付款金额',
            'reconcileDate' => '对账日期',
            'status' => '状态',

        ];
        $name =$this->title;
        exportXlsData($name,$title,$list);
        exit();
    }
}